﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Routing;
using System.Collections;
using ASPMVCUtil.Helpers;
using System.Linq.Expressions;
using ASPMVCUtil.Models;

namespace System.Web.Mvc.Html
{
    public static class Input
    {
        /// <summary>
        /// Retorna un IEnumerable listo para ser usado en un DropDownList
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="listaOriginal">Listado de elementos seleccionables</param>
        /// <param name="valueField">Nombre de la propiedad de los elementos que se debe usar como valor</param>
        /// <param name="textField">Nombre de la propiedad de los elementos que se debe usar como texto (visible)</param>
        /// <param name="selectedValue">Opcional. Valor seleccionado</param>
        /// <exception cref="System.ArgumentException">Si el valueField o textField no se peuden obtener</exception>
        /// <returns></returns>
        public static IEnumerable<SelectListItem> selectListOpcionSeleccione(this HtmlHelper helper, IEnumerable listaOriginal, string valueField, 
            string textField, string selectedValue = null)
        {
            IList<SelectListItem> lista = new List<SelectListItem>();
            var sli = new SelectListItem();
            sli.Value = "";
            sli.Text = "[Seleccione]";
            lista.Add(sli);
            foreach (var item in listaOriginal)
            {
                sli = new SelectListItem();
                try
                {
                    sli.Value = item.GetType().GetProperty(valueField).GetValue(item, null).ToString();
                    if (selectedValue != null && sli.Value.Equals(selectedValue))
                        sli.Selected = true;
                }
                catch (NullReferenceException ex)
                {                    
                    throw new ArgumentException("La propiedad no existe o no se puede leer", valueField);
                }
                try
                {
                    sli.Text = item.GetType().GetProperty(textField).GetValue(item, null).ToString();
                }
                catch (NullReferenceException ex)
                {
                    throw new ArgumentException("La propiedad no existe o no se puede leer", textField);
                }
                lista.Add(sli);
	        }
            return lista;
        }
        /// <summary>
        /// Habilita a un select (padre) para que al cambiar actualice los valores de otro (hijo) pidiéndolos por AJAX
        /// </summary>
        /// <param name="htmlHelper">HtmlHelper</param>
        /// <param name="urlHelper">UrlHelper</param>
        /// <param name="rutaAccion">Ruta de la acción GET donde se solicitarán los nuevos valores del hijo</param>
        /// <param name="trigerId">Id del select que lanza la actualización</param>
        /// <param name="camposValores">Ids de los select cuyos valores se envían</param>
        /// <param name="hijoId">Id del select hijo</param>
        /// <param name="campoValor">Campo de dónde se debe sacar el value para los elementos del select hijo</param>
        /// <param name="campoTexto">Campo de dónde se debe sacar el texto para los elementos del select hijo</param>
        /// <param name="opcional">Opcional. Indica si el ddl es opcional y por tanto se debe incluír en primer lugar la opciíon [Seleccione]</param>
        /// <param name="botonId">Opcional. Id del botón que debe desabilitarse mientras se hace el llamado asincrónico</param>
        public static MvcHtmlString ddlCascada(this HtmlHelper htmlHelper, UrlHelper urlHelper, string rutaAccion, string trigerId, string[] selectValores, 
            string hijoId,
            string campoValor, string campoTexto, bool opcional = false, string botonId = null)
        {
            //Imagen indicadora
            var imagen = htmlHelper.Image(urlHelper.Content("~/Images/ASPMVCUtil/loading.gif"), "Cargando...", new { style = "border: 0px; display: none; margin-top: -2px" }, "imgCargando" + hijoId);

            //Div de error
            TagBuilder div = new TagBuilder("div");
            div.GenerateId(hijoId + "-message-failure");

            //Script jQuery
            TagBuilder script = new TagBuilder("script");
            script.MergeAttribute("type", "text/javascript");
            var s = JS.outl();
            s += JS.outl("    $(document).ready(function () {");
            s += JS.outl("        $('select#" + trigerId + "').change(");

            s += JS.outl("function() {");
            s += JS.outl("                var parametros = '';");
            s += JS.outl("                var valor = true;");
            for (int i = 0; i < selectValores.Length; i++)
            {
                s += JS.outl("                valor = valor && $('select#" + selectValores[i] + " > option:selected').attr('Value') != '';");
                if (i == 0)
                    s += JS.outl("                parametros += 'id" + (i + 1) + "=' + $('select#" + selectValores[i] + " > option:selected').attr('Value');");
                else
                    s += JS.outl("                parametros += '&id" + (i + 1) + "=' + $('select#" + selectValores[i] + " > option:selected').attr('Value');");
            }
            if (opcional)
                s += JS.outl("                if(valor) {");
            s += JS.outl("                $('select#" + hijoId + "').attr('class', 'ddl-actualizando');");
            s += JS.outl("                $('#imgCargando" + hijoId + "').show();");
            if (botonId != null)
                s += JS.outl("                $('input#" + botonId + "').attr('disabled', true);");
            s += JS.outl("                $('select#" + hijoId + "').attr('disabled', true);");
            s += JS.outl("                $('select#" + hijoId + "').html('<option value=\"\">Actualizando...</option>');");
            s += JS.outl("                $('select#" + hijoId + "').change();");
            s += JS.outl("                $.ajax({");
            s += JS.outl("                    type: 'GET',");
            s += JS.outl("                    contentType: 'application/json;charset=utf-8',");
            s += JS.outl("                    url: '" + rutaAccion + "?' + parametros,");
            s += JS.outl("                    data: '',");
            s += JS.outl("                    dateType: 'json',");
            s += JS.outl("                    success: function (data) {");
            s += JS.outl("                        var options = '<option value=\"\">[Seleccione]</option>';");
            s += JS.outl("                        if (data.length > 0) {");
            s += JS.outl("                            for (i in data) {");
            s += JS.outl("                                options += '<option value=\"' + data[i]." + campoValor + " + '\">' + data[i]." + campoTexto + " + '</option>';");
            s += JS.outl("                            }");
            s += JS.outl("                        }");
            s += JS.outl("                        $('select#" + hijoId + "').html(options);");
            s += JS.outl("                    },");
            s += JS.outl("                    error: function (XMLHttpRequest, textStatus, errorThrown) {");
            s += JS.outl("                        ponerMensaje('" + hijoId + "', 'Ocurrió un problema inesperado', true, 1000)");
            s += JS.outl("                ");
            s += JS.outl("                    },");
            s += JS.outl("                    complete: function (XMLHttpRequest, textStatus) {");
            s += JS.outl("                        $('#imgCargando" + hijoId + "').fadeOut(400, function() {");
            s += JS.outl("                             $('select#" + hijoId + "').attr('class', 'ddl');");
            s += JS.outl("                        });");
            s += JS.outl("                        $('select#" + hijoId + "').removeAttr('disabled');");
            if (botonId != null)
                s += JS.outl("                        $('input#" + botonId + "').removeAttr('disabled');");
            s += JS.outl("                    }");
            s += JS.outl("                });");
            if (opcional)
            {
                s += JS.outl("                }");
                s += JS.outl("                else {");
                s += JS.outl("                    $('select#" + hijoId + "').change();");
                s += JS.outl("                    $('select#" + hijoId + "').html('<option value=\"\">[Seleccione]</option>');");
                s += JS.outl("                }");
            }
            s += JS.outl("            });");
            s += JS.outl("    });");

            script.InnerHtml = s;
            return MvcHtmlString.Create(imagen.ToString() + div.ToString(TagRenderMode.Normal) + script.ToString(TagRenderMode.Normal));
        }

        /// <summary>
        /// htmlHelper que permite construír un submit button
        /// </summary>
        /// <param name="helper"></param>
        /// <param name="name"></param>
        /// <param name="value"></param>
        /// <param name="id"></param>
        /// <param name="atributosHtml"></param>
        /// <returns></returns>
        public static MvcHtmlString SubmitButton(this HtmlHelper htmlHelper, string name, string value, string id = null, object atributosHtml = null)
        {
            var builder = new TagBuilder("input");
            builder.MergeAttribute("type", "submit");
            if (id != null)
                builder.GenerateId(id);
            builder.MergeAttribute("name", name);
            if (id == null)
                builder.GenerateId(name);
            else
                builder.GenerateId(id);
            builder.MergeAttribute("value", value);
            builder.MergeAttributes(new RouteValueDictionary(atributosHtml));
            var img = builder.ToString(TagRenderMode.SelfClosing);
            return MvcHtmlString.Create(img);
        }

        /// <summary>
        /// Helper to create an Autocomplete widget for a list with many items.
        /// The view that contains it can autocomplete css class defined, will be applied to text field when not focused, ex.: 
        ///    .autocomplete 
        ///    {
        ///        font-style: italic;
        ///        color: #666;
        ///    }
        /// El modelo usado debe contener una propiedad adcicional llamada como la original más "Texto" de tipo string
        /// </summary>
        /// <typeparam name="TItem">Tipo del los items</typeparam>
        /// <param name="htmlHelper">htmlHelper</param>
        /// <param name="items">Lista de items del tipo TItem</param>
        /// <param name="valueField">Nombre de la propiedad legible de TItem de donde se obtendrá el valor del elemento de la lista</param>
        /// <param name="textField">Nombre de la propiedad legible de TItem de donde se obtendrá el texto del elemento de la lista</param>
        /// <param name="fieldId">Id del campo</param>
        /// <param name="fieldName">Name del campo</param>
        /// <param name="valor">Opcional. Valor actual del campo, si no se incluye el texto será ignorado</param>
        /// <param name="texto">Opcional. Texto actual del campo, si no se incluye el valor será ignorado</param>
        /// <param name="htmlAttributes">Opcional. Objeto que contiene atributos html a poner al campo de texto</param>
        /// <param name="htmlAttributes">Opcional. Número mínimo de caracteres que se deben ingresar para que el autocompletar se despliegue</param>
        /// <returns></returns>
        public static MvcHtmlString Autocomplete<TItem>(this HtmlHelper htmlHelper, IEnumerable<TItem> items,
            string valueField, string textField, string fieldId, string fieldName, string value, string text, object htmlAttributes = null,
            int minimoCaracteres = 1)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                text = "Empiece a escribir...";
            }
            int intValue = 0;
            bool hasValue = !string.IsNullOrWhiteSpace(value) || (int.TryParse(value, out intValue) && intValue > 0);
            var lista = "[";
            int i = 0;
            foreach (TItem item in items)
            {
                var propiedadValor = item.GetType().GetProperty(valueField);
                if (propiedadValor == null || !propiedadValor.CanRead)
                    throw new ArgumentException("La propiedad " + valueField + " indicada como valueField no existe en el tipo del listado o no se puede leer, revise que no sea un error tipográfico");
                var propiedadTexto = item.GetType().GetProperty(textField);
                if (propiedadTexto == null || !propiedadTexto.CanRead)
                    throw new ArgumentException("La propiedad " + textField + " indicada como textField no existe en el tipo del listado o no se puede leer, revise que no sea un error tipográfico");
                if (i != 0)
                    lista += ",";
                var itemValue = propiedadValor.GetValue(item, null).ToString();
                var itemLabel = propiedadTexto.GetValue(item, null).ToString();
                lista += "{ label : '" + itemLabel + "', value: '" + itemValue + "' }";
                if (hasValue)
                {
                    if (itemValue.Equals(value))
                    {
                        text = itemLabel;
                    }
                }
                i++;
            }
            lista += "]";

            var atributosHtml = new RouteValueDictionary(htmlAttributes);

            //Si no hay valor pregargado pone el hint
            if (!hasValue)
            {
                value = "";
                var clase = "autocomplete";
                if (atributosHtml.ContainsKey("class"))
                {
                    object valorClase;
                    atributosHtml.TryGetValue("class", out valorClase);
                    if (valorClase != null)
                    {
                        atributosHtml.Remove("class");
                        clase += " " + valorClase;
                    }
                }
                atributosHtml.Add("class", clase);
            }

            //Setea el prefijo del nombre para que quede exactamente como se envía en los text box
            htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix = "";

            var au = InputExtensions.TextBox(htmlHelper, fieldName + "Text", text, atributosHtml);
            var id = InputExtensions.TextBox(htmlHelper, fieldName, value, new { style = "visibility: hidden; width: 0px" });

            //Crea el js
            TagBuilder script = new TagBuilder("script");
            script.MergeAttribute("type", "text/javascript");

            var s = "";
            s += JS.outl();
            s += JS.outl("$(function () {");
            s += JS.outl("//Cuando se enfoca el campo y estaba presente el hint, lo quita");
            s += JS.outl("    $('#" + fieldId + "Text').focus(function() {");
            s += JS.outl("        if($('#" + fieldId + "Text').val() == 'Empiece a escribir...') {");
            s += JS.outl("            $('#" + fieldId + "Text').val('');");
            s += JS.outl("            $('#" + fieldId + "Text').removeClass('autocomplete');");
            s += JS.outl("        }");
            s += JS.outl("    });");
            s += JS.outl();
            s += JS.outl("//Cuando se enfoca sale del campo y el valor es vacío, pone de nuevo el hint");
            s += JS.outl("    $('#" + fieldId + "Text').blur(function() {");
            s += JS.outl("        if($('#" + fieldId + "Text').val() == '') {");
            s += JS.outl("            $('#" + fieldId + "Text').val('Empiece a escribir...');");
            s += JS.outl("            $('#" + fieldId + "Text').addClass('autocomplete');");
            s += JS.outl("        }");
            s += JS.outl("    });");
            s += JS.outl("    $('#" + fieldId + "Text').val('" + text + "');");
            s += JS.outl("    $('#" + fieldId + "').val('" + value + "');");
            s += JS.outl();
            s += JS.outl("//Función para que el usuario no tenga que escribir las tíldes mientras filtra");
            s += JS.outl("    var accentMap = {");
            s += JS.outl("        'á': 'a',");
            s += JS.outl("        'é': 'e',");
            s += JS.outl("        'í': 'e',");
            s += JS.outl("        'ó': 'o',");
            s += JS.outl("        'ú': 'u'");
            s += JS.outl("    };");
            s += JS.outl();
            s += JS.outl("    var normalize = function (term) {");
            s += JS.outl("        var ret = '';");
            s += JS.outl("        for (var i = 0; i < term.length; i++) {");
            s += JS.outl("            ret += accentMap[term.charAt(i)] || term.charAt(i);");
            s += JS.outl("        }");
            s += JS.outl("        return ret;");
            s += JS.outl("    };");
            s += JS.outl();
             s += JS.outl("//Variable que contiene la lista de elementos (value, label) del autocmpletar");
            s += JS.outl("    var a" + fieldId + " = " + lista + ";");
            s += JS.outl("    var " + fieldId + "Seleccionado = false;");
            s += JS.outl("    $('#" + fieldId + "Text').autocomplete({");
            s += JS.outl("        source: function (request, response) {");
            s += JS.outl("            var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), \"i\");");
            s += JS.outl("            response($.grep(a" + fieldId + ", function (value) {");
            s += JS.outl("                value = value.label || value.value || value;");
            s += JS.outl("                return matcher.test(value) || matcher.test(normalize(value));");
            s += JS.outl("            }));");
            s += JS.outl("        },");
            s += JS.outl("//Apenas se teclea busca");
            s += JS.outl("        delay: 0,");
            s += JS.outl("//Busca desde que se han ingresado dos caracteres");
            s += JS.outl("        minLength: " + minimoCaracteres + ",");
            s += JS.outl("//Cuando se selecciona un elemento actualiza el campo y el campo oculto que contiene el valor");
            s += JS.outl("        select: function (event, ui) {");
            s += JS.outl("            $('#" + fieldId + "').val(ui.item.value);");
            s += JS.outl("            $('#" + fieldId + "Text').val(ui.item.label);");
            s += JS.outl("            " + fieldId + "Seleccionado = true;");
            s += JS.outl("            return false;");
            s += JS.outl("        },");
            s += JS.outl("//Cuando se enfoca un elemento no hace nada");
            s += JS.outl("        focus: function (event, ui) {");
            s += JS.outl("        },");
            s += JS.outl("//Antes de buscar, si no se ha seleccionado un elemento deja el valor vacío");
            s += JS.outl("        search: function (event, ui) {");
            s += JS.outl("            if(" + fieldId + "Seleccionado == false) {");
            s += JS.outl("                $('#" + fieldId + "').val('');");
            s += JS.outl("            }");
            s += JS.outl("            else {");
            s += JS.outl("                " + fieldId + "Seleccionado = false;");
            s += JS.outl("            }");
            s += JS.outl("        },");
            s += JS.outl("//Si el valor cambia, si no se ha seleccionado un elemento deja el valor vacío");
            s += JS.outl("        change: function(event, ui) {");
            s += JS.outl("            if(" + fieldId + "Seleccionado == false) {");
            s += JS.outl("                $('#" + fieldId + "').val('');");
            s += JS.outl("            }");
            s += JS.outl("            else {");
            s += JS.outl("                " + fieldId + "Seleccionado = false;");
            s += JS.outl("            }");
            s += JS.outl("        }");
            s += JS.outl("    });");
            s += JS.outl("});");

            script.InnerHtml = s;

            return MvcHtmlString.Create(JS.outl() + script.ToString(TagRenderMode.Normal) + au.ToString() + JS.outl()
                + id.ToString());
        }

        /// <summary>
        /// Helper to create an Autocomplete widget for remote JSON list with many items.
        /// The view that contains it can autocomplete css class defined, will be applied to text field when not focused, ex.: 
        ///    .autocomplete 
        ///    {
        ///        font-style: italic;
        ///        color: #666;
        ///    }
        /// El modelo usado debe contener una propiedad adcicional llamada como la original más "Texto" de tipo string
        /// </summary>
        /// <typeparam name="TItem">Tipo del los items</typeparam>
        /// <param name="htmlHelper">htmlHelper</param>
        /// <param name="sourceUrl">Url to source. The source has to receive the GET attribute q. Ex.: /Home/Search, so the request will be /Home/Search?q=a when the user types a</param>
        /// <param name="valueField">Nombre de la propiedad legible de TItem de donde se obtendrá el valor del elemento de la lista</param>
        /// <param name="textField">Nombre de la propiedad legible de TItem de donde se obtendrá el texto del elemento de la lista</param>
        /// <param name="fieldId">Id del campo</param>
        /// <param name="fieldName">Name del campo</param>
        /// <param name="value">Opcional. Valor actual del campo, si no se incluye el texto será ignorado</param>
        /// <param name="text">Opcional. Texto actual del campo, si no se incluye el valor será ignorado</param>
        /// <param name="htmlAttributes">Opcional. Objeto que contiene atributos html a poner al campo de texto</param>
        /// <param name="htmlAttributes">Opcional. Número mínimo de caracteres que se deben ingresar para que el autocompletar se despliegue</param>
        /// <returns></returns>
        public static MvcHtmlString AutocompleteAjax(this HtmlHelper htmlHelper, string sourceUrl,
            string valueField, string textField, string fieldId, string fieldName, string value, string text, object htmlAttributes = null,
            int minCharsToSearch = 1)
        {
            var atributosHtml = new RouteValueDictionary(htmlAttributes);

            //Si no hay valor precargado pone el hint
            int intValue = 0;
            if (string.IsNullOrWhiteSpace(text) || string.IsNullOrWhiteSpace(value) || (int.TryParse(value, out intValue) && intValue == 0))
            {
                text = "Empiece a escribir...";
                value = "";
                var clase = "autocomplete";
                if (atributosHtml.ContainsKey("class"))
                {
                    object valorClase;
                    atributosHtml.TryGetValue("class", out valorClase);
                    atributosHtml.Remove("class");
                    clase += " " + valorClase.ToString();
                }
                atributosHtml.Add("class", clase);
            }

            //Setea el prefijo del nombre para que quede exactamente como se envía en los text box
            htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix = "";

            var au = InputExtensions.TextBox(htmlHelper, fieldName + "Text", text, atributosHtml);
            var id = InputExtensions.TextBox(htmlHelper, fieldName, value, new { style = "visibility: hidden; width: 0px" });

            //Crea el js
            TagBuilder script = new TagBuilder("script");
            script.MergeAttribute("type", "text/javascript");

            var s = "";
            s += JS.outl();
            s += JS.outl("$(function () {");
            s += JS.outl("//Cuando se enfoca el campo y estaba presente el hint, lo quita");
            s += JS.outl("    $('#" + fieldId + "Text').focus(function() {");
            s += JS.outl("        if($('#" + fieldId + "Text').val() == 'Empiece a escribir...') {");
            s += JS.outl("            $('#" + fieldId + "Text').val('');");
            s += JS.outl("            $('#" + fieldId + "Text').removeClass('autocomplete');");
            s += JS.outl("        }");
            s += JS.outl("    });");
            s += JS.outl();
            s += JS.outl("//Cuando se enfoca sale del campo y el valor es vacío, pone de nuevo el hint");
            s += JS.outl("    $('#" + fieldId + "Text').blur(function() {");
            s += JS.outl("        if($('#" + fieldId + "Text').val() == '') {");
            s += JS.outl("            $('#" + fieldId + "Text').val('Empiece a escribir...');");
            s += JS.outl("            $('#" + fieldId + "Text').addClass('autocomplete');");
            s += JS.outl("        }");
            s += JS.outl("    });");
            s += JS.outl();
            if (value.Equals(""))
            {
                s += JS.outl("    $('#" + fieldId + "Text').val('Empiece a escribir...');");
                s += JS.outl("    $('#" + fieldId + "').val('');");
            }
            s += JS.outl("//Función para que el usuario no tenga que escribir las tíldes mientras filtra");
            s += JS.outl("    var accentMap = {");
            s += JS.outl("        'á': 'a',");
            s += JS.outl("        'é': 'e',");
            s += JS.outl("        'í': 'e',");
            s += JS.outl("        'ó': 'o',");
            s += JS.outl("        'ú': 'u'");
            s += JS.outl("    };");
            s += JS.outl();
            s += JS.outl("    var normalize = function (term) {");
            s += JS.outl("        var ret = '';");
            s += JS.outl("        for (var i = 0; i < term.length; i++) {");
            s += JS.outl("            ret += accentMap[term.charAt(i)] || term.charAt(i);");
            s += JS.outl("        }");
            s += JS.outl("        return ret;");
            s += JS.outl("    };");
            s += JS.outl();
            s += JS.outl("//Variable que contiene la lista de elementos (value, label) del autocmpletar");
            s += JS.outl("    var " + fieldId + "Seleccionado = false;");
            s += JS.outl("      var cache = {}, lastXhr;");
            s += JS.outl("    $('#" + fieldId + "Text').autocomplete({");
            s += JS.outl("          source: function (request, response) {");
            s += JS.outl("              var term = request.term;");
			s += JS.outl("              if ( term in cache ) {");
			s += JS.outl("        		    response( cache[ term ] );");
			s += JS.outl("        		    return;");
			s += JS.outl("        	    }");
            s += JS.outl();
            s += JS.outl("        	    lastXhr = $.getJSON( '" + sourceUrl + "', request, function( data, status, xhr ) {");
			s += JS.outl("        		data = $.map( data, function( item ) {");
			s += JS.outl("        			return {");
			s += JS.outl("        				label: item." + textField + ",");
			s += JS.outl("        				value: item." + valueField);
			s += JS.outl("        			}");
            s += JS.outl("        		});");
            s += JS.outl("        		cache[ term ] = data;");
			s += JS.outl("        		if ( xhr === lastXhr ) {");
			s += JS.outl("        			response( data );");
			s += JS.outl("        		}");
			s += JS.outl("        	});");
            s += JS.outl("        },");
            s += JS.outl("//Apenas se teclea busca");
            s += JS.outl("        delay: 0,");
            s += JS.outl("//Busca desde que se han ingresado dos caracteres");
            s += JS.outl("        minLength: " + minCharsToSearch + ",");
            s += JS.outl("//Cuando se selecciona un elemento actualiza el campo y el campo oculto que contiene el valor");
            s += JS.outl("        select: function (event, ui) {");
            s += JS.outl("            $('#" + fieldId + "').val(ui.item.value);");
            s += JS.outl("            $('#" + fieldId + "Text').val(ui.item.label);");
            s += JS.outl("            " + fieldId + "Seleccionado = true;");
            s += JS.outl("            return false;");
            s += JS.outl("        },");
            s += JS.outl("//Cuando se enfoca un elemento no hace nada");
            s += JS.outl("        focus: function (event, ui) {");
            s += JS.outl("        },");
            s += JS.outl("//Si el valor cambia, si no se ha seleccionado un elemento deja el valor vacío");
            s += JS.outl("        change: function(event, ui) {");
            s += JS.outl("            if(" + fieldId + "Seleccionado == false) {");
            s += JS.outl("                $('#" + fieldId + "').val('');");
            s += JS.outl("            }");
            s += JS.outl("            else {");
            s += JS.outl("                " + fieldId + "Seleccionado = false;");
            s += JS.outl("            }");
            s += JS.outl("        }");
            s += JS.outl("    });");
            s += JS.outl("});");

            script.InnerHtml = s;

            return MvcHtmlString.Create(JS.outl() + script.ToString(TagRenderMode.Normal) + au.ToString() + JS.outl()
                + id.ToString());
        }
    }
}
